//
// Created by lenovo on 2024/7/2.
//
#include "./Collision.h"
namespace Game::Phy::Collision{

    //AABB
    bool AABB::intersectWithAABB(Game::Phy::Collision::AABB &aabb)  {
        return (position.x <= aabb.position.x + aabb.scale.x && position.x + scale.x >= aabb.position.x) &&
               (position.y <= aabb.position.y + aabb.scale.y && position.y + scale.y >= aabb.position.y);
    }
    bool AABB::intersectWithCircle(CircleCollider& circle) {
        float nearestX = std::max(position.x, std::min(circle.position.x, position.x + scale.x));
        float nearestY = std::max(position.y, std::min(circle.position.y, position.y + scale.y));
        float dx = nearestX - circle.position.x;
        float dy = nearestY - circle.position.y;
        return (dx * dx + dy * dy) <= (circle.radius * circle.radius);
    }

    bool AABB::intersectWithPoint(PointCollider& point) {
        return (point.position.x >= position.x && point.position.x <= position.x + scale.x) &&
               (point.position.y >= position.y && point.position.y <= position.y + scale.y);
    }

    //Circle
    bool CircleCollider::intersectWithAABB(Game::Phy::Collision::AABB &aabb) {
        float nearestX = std::max(aabb.position.x, std::min(position.x, aabb.position.x + aabb.scale.x));
        float nearestY = std::max(aabb.position.y, std::min(position.y, aabb.position.y + aabb.scale.y));
        float dx = nearestX - position.x;
        float dy = nearestY - position.y;
        return (dx * dx + dy * dy) <= (radius * radius);
    }

    bool CircleCollider::intersectWithCircle(Game::Phy::Collision::CircleCollider &circle)  {
        float dx = position.x - circle.position.x;
        float dy = position.y - circle.position.y;
        float distance = std::sqrt(dx * dx + dy * dy);
        return distance <= (radius + circle.radius);
    }

    bool CircleCollider::intersectWithPoint(PointCollider& point) {
        float dx = position.x - point.position.x;
        float dy = position.y - point.position.y;
        float distance = std::sqrt(dx * dx + dy * dy);
        return distance <= radius;
    }

    //Point
    bool PointCollider::intersectWithAABB(Game::Phy::Collision::AABB &aabb) {
        return (position.x >= aabb.position.x && position.x <= aabb.position.x + aabb.scale.x) &&
               (position.y >= aabb.position.y && position.y <= aabb.position.y + aabb.scale.y);
    }

    bool PointCollider::intersectWithCircle(Game::Phy::Collision::CircleCollider &circle) {
        float dx = position.x - circle.position.x;
        float dy = position.y - circle.position.y;
        float distance = std::sqrt(dx * dx + dy * dy);
        return distance <= circle.radius;
    }

    bool PointCollider::intersectWithPoint(Game::Phy::Collision::PointCollider &point)  {
        return (position.x == point.position.x && position.y == point.position.y);
    }
}